package com.zpark.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @PackageName: com.zpark.cglib
 * @ClassName: CglibProxy
 * @Description:
 * @author: RZS
 * @date: 2023/3/30  9:50
 */
public class CglibProxy {
    public static void main(String[] args) {
        // 创建切面类对象
        final CglibAspect aspect = new CglibAspect();
        /**
         * 动态代理：
         *  特点：字节码随用随创建，随用随加载
         *  作用：不修改源码的基础上对方法增强
         *  分类：
         *      基于接口的动态代理
         *      基于子类的动态代理
         *  基于子类的动态代理：
         *      涉及的类：Enhancer
         *      提供者：第三方cglib库
         *  如何创建代理对象：
         *      使用Enhancer类中的create方法
         *  创建代理对象的要求：
         *      被代理类不能是最终类
         *  create方法的参数：
         *      Class：字节码
         *          它是用于指定被代理对象的字节码。
         *
         *      Callback：用于提供增强的代码
         *          它是让我们写如何代理。我们一般都是些一个该接口的实现类，通常情况下都是匿名内部类，但不是必须的。
         *          此接口的实现类都是谁用谁写。
         *          我们一般写的都是该接口的子接口实现类：MethodInterceptor
         */
//        Enhancer.create(IAdminDao.class, new MethodInterceptor() {
//            @Override
//            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//
//            }
//        })

        // 被代理的目标对象
        IAdminDao adminDao = (IAdminDao) Enhancer.create(IAdminDao.class, (MethodInterceptor) (o, method, objects, methodProxy) -> {
            aspect.myBefore();
            Object invoke = method.invoke(new IAdminDao(), args);
            aspect.myAfter();
            return invoke;
        });

        adminDao.add();
    }
}
